package cn.tedu.knows.portal.service.impl;

import cn.tedu.knows.portal.mapper.UserMapper;
import cn.tedu.knows.portal.model.Permission;
import cn.tedu.knows.portal.model.Role;
import cn.tedu.knows.portal.model.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Component;

import java.util.Arrays;
import java.util.List;

//将UserDetailsServiceImpl类对象保存到Spring容器
@Component
public class UserDetailsServiceImpl
                            implements UserDetailsService {
    //UserDetailsService是Spring-Security提供的
    //Spring-Security框架验证用户登录需要使用这个接口的实现类

    @Autowired
    private UserMapper userMapper;

    //用户登录时,Spring-Security会将用户输入的用户名传递到
    // 这个方法的参数中,我们看到的loadUserByUsername的参数就是用户名

    //方法的返回值UserDetails类型也是Spring-Security框架要求的
    // UserDetails(用户详情)对象包含了登录和权限系统需要的属性
    // 任何项目都可以使用这个类型的对象进行权限管理
    //这个方法的目标就是将这个对象正确的赋值并返回
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {

        //根据用户名获得用户
        User user=userMapper.findUserByUsername(username);
        if(user==null){
            //如果用户不存在登录失败
            return null;
        }
        //根据用户的id查询用户的所有权限
        List<Permission> ps= userMapper
                .findUserPermissionsById(user.getId());
        //根据登录需求,需要将ps对象转换为String[]类型
        String[] auth=new String[ps.size()];
        int i=0;
        for(Permission p : ps){
            auth[i]=p.getName();
            i++;
        }
        //新增的代码↓↓↓↓↓↓↓↓
        //查询当前用户的所有角色
        List<Role> roles=userMapper.findUserRolesById(
                user.getId());
        auth= Arrays.copyOf(auth,
                        auth.length+roles.size());
        for(Role role:roles){
            auth[i++]=role.getName();
        }
        //新增代码结束↑↑↑↑↑↑

        //构建UserDetails对象
        UserDetails u= org.springframework.security.core.userdetails
                .User.builder()
                .username(user.getUsername())
                .password(user.getPassword())
                //getLocked返回值为0,和1比较结果为false,既不锁定
                .accountLocked(user.getLocked()==1)
                //getEnabled返回值为1,和0比较结果为false,既可用
                .disabled(user.getEnabled()==0)
                .authorities(auth)//赋予当前登录用户权限
                .build();
        //最后千万别忘了返回u
        return  u;
    }
}
